﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GestoreSuperProgetto.Model;
using SharpSvn;
using System.IO;

namespace GestoreSuperProgetto
{
    public partial class ProjectsManagment : Form
    {
        LABEL labelTrunk = null;

        public ProjectsManagment()
        {
            InitializeComponent();
        }

        private void saveBtn_Click(object sender, EventArgs e)
        {
            var man = (Owner as StartForm).DataManager;

            if (urlTxt.Text != "" && projectNameTxt.Text != "")
            {

                PROJECT proj = new PROJECT()
                {
                    NAME = projectNameTxt.Text,
                    URL = urlTxt.Text,
                };
                man.AddToPROJECTS(proj);

                man.AddToLABEL_PROJECTS(new LABEL_PROJECTS()
                {
                    LABEL = labelTrunk,
                    PROJECT = proj,
                });

                man.SaveChanges();
                //man.OpenDatabaseSession();
                projectNameTxt.Text = "";
                urlTxt.Text = "";

                updateCurrentConfiguration();
            }
        }

        private void saveSuperProjectBtn_Click(object sender, EventArgs e)
        {
            var man = (Owner as StartForm).DataManager;


            if (superProjectNameTxt.ReadOnly)
            {
                SUPERPROJECT sprj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;
                sprj.DEFAULTDIRECTORY = defaultDirTxt.Text;
            }
            else
            {
                SUPERPROJECT superProj = new SUPERPROJECT() {
                    NAME = superProjectNameTxt.Text,
                    DEFAULTDIRECTORY = defaultDirTxt.Text,
                };
                //superProj.ID = man.GetSuperProjectNextID();
                

                man.AddToSUPERPROJECTS(superProj);

                man.AddToLABEL_SUPERPROJECTS(new LABEL_SUPERPROJECTS() {
                    SUPERPROJECT = superProj,
                    LABEL = labelTrunk,
                });

                man.SaveChanges();

                var users = man.USERS;
                //var tablePerm = man.PERMISSIONS;
                foreach (USER user in users)
                {
                    PERMISSION perms = new PERMISSION() { 
                        PREAD = 1,
                        PWRITE = 0,
                        SUPERPROJECT = superProj,
                        USER = user,
                    };

                    man.AddToPERMISSIONS(perms);
                }
            }
            man.SaveChanges();
            
            superProjectNameTxt.Text = "";
            defaultDirTxt.Text = "";


            updateCurrentConfiguration(true);
        }

        private void ProjectsManagment_Load(object sender, EventArgs e)
        {
            var man = (Owner as StartForm).DataManager;

            labelTrunk = (from lbl in man.LABELS
                          where lbl.ID == 1
                          select lbl).FirstOrDefault();

            updateCurrentConfiguration(true);
        }

        private void usableProjectlbx_SelectedIndexChanged(object sender, EventArgs e)
        {
            addBtn.Enabled = true;
        }

        private void addBtn_Click(object sender, EventArgs e)
        {
            SUPERPROJECT currentSuperPrj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;
            var man = (Owner as StartForm).DataManager;
            
            var lblSPrj = (from lblSuperPrj in currentSuperPrj.LABEL_SUPERPROJECTS
                          where lblSuperPrj.ID_LABEL == 1
                          select lblSuperPrj).SingleOrDefault();

            foreach (PROJECT prj in usableProjectlbx.SelectedItems)
            {
                var lblPrj = (from lprj in man.LABEL_PROJECTS
                              where lprj.ID_LABEL == 1 && lprj.ID_PROJECT == prj.ID
                              select lprj).FirstOrDefault();

                lblSPrj.LABEL_PROJECTS.Add(lblPrj);
                //SuperProjectsProjects spp = new SuperProjectsProjects();
                //spp.IDProject = prj.ID;
                //spp.IDSuperProject = currentSuperPrj.ID;

                //man.SuperProjectsProjects.InsertOnSubmit(spp);
            }

            man.SaveChanges();

            updateCurrentConfiguration();
        }

        private void currentCfglbx_SelectedIndexChanged(object sender, EventArgs e)
        {
            delBtn.Enabled = true;
        }

        private void saveChangesBtn_Click(object sender, EventArgs e)
        {
            SUPERPROJECT currentSuperPrj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;
            var man = (Owner as StartForm).DataManager;

            man.DeleteObject(currentSuperPrj);

            man.SaveChanges();
        }

        private bool inizialize = true;

        private void updateCurrentConfiguration()
        {
            updateCurrentConfiguration(false);
        }

        private void updateCurrentConfiguration(bool fillCombo)
        {
            var man = (Owner as StartForm).DataManager;
            var pippo = man.LABEL_PROJECTS;
            var pippo2 = man.PROJECTS;
            if (fillCombo)
            {
                BindingSource superProjSource = new BindingSource();

                if (man.ActiveUser.ISADMIN == 1)
                    superProjSource.DataSource = man.SUPERPROJECTS;
                else
                {
                    man.ActiveUser.PERMISSIONS.Load();
                    var adminPrj = (from perm in man.ActiveUser.PERMISSIONS
                                         where perm.PADMIN > 0
                                          orderby perm.SUPERPROJECT.NAME
                                         select perm.SUPERPROJECT).ToList();

                    superProjSource.DataSource = adminPrj;
                }
                currentSuperPrjcmb.DataSource = superProjSource;
            }
            BindingSource usableProjectSource = new BindingSource();
            BindingSource usableSuperProjectSource = new BindingSource();
            if (currentSuperPrjcmb.SelectedItem != null)
            {                
                var curPrj = (currentSuperPrjcmb.SelectedItem as SUPERPROJECT);

                curPrj.LABEL_SUPERPROJECTS.Load();

                var labelTrunkSPrj = (from lblSproj in curPrj.LABEL_SUPERPROJECTS
                                      where lblSproj.ID_LABEL == 1
                                      select lblSproj).SingleOrDefault();

                //labelTrunkSPrj.LABEL_PROJECTS.Load();

                var listUsaged = (from lblPrj in labelTrunkSPrj.LABEL_PROJECTS.CreateSourceQuery().Include("PROJECT")
                            let prj = lblPrj.PROJECT
                            where lblPrj.ID_LABEL == 1
                            orderby prj.NAME
                            select prj).ToList();

                var availablePrj = (from proj in man.PROJECTS
                                    orderby proj.NAME
                                    select proj).ToList().Except(listUsaged);

                usableProjectSource.DataSource = availablePrj;

                var list = (from sPrj in man.SUPERPROJECTS
                            orderby sPrj.NAME
                            select sPrj).ToList();

                list.Remove(curPrj);

                var list2 = ((from lsp in curPrj.LABEL_SUPERPROJECTS.CreateSourceQuery().Include("LABEL_SUPERPROJECTS_CHILD").Include("LABEL_SUPERPROJECTS_CHILD.SUPERPROJECT")
                                       where lsp.ID_LABEL == 1
                                       orderby lsp.SUPERPROJECT.NAME
                                       from sp in lsp.LABEL_SUPERPROJECTS_CHILD
                                        orderby sp.SUPERPROJECT.NAME
                                       select sp.SUPERPROJECT));

                foreach (var sproj in list2)
                    list.Remove(sproj);
                
                usableSuperProjectSource.DataSource = list;
                               
                BindingSource source = new BindingSource();
                source.DataSource = listUsaged;
                //currentCfglbx.DisplayMember = "Name";
                //currentCfglbx.ValueMember = "URL";
                currentCfglbx.DataSource = source;
                

                BindingSource source2 = new BindingSource();
                source2.DataSource = list2;
                //currentDependsCfglbx.DisplayMember = "Name";
                //currentDependsCfglbx.ValueMember = "DefaultDir";
                currentDependsCfglbx.DataSource = source2;
            }
            else
            {
                usableProjectSource.DataSource = (from proj in man.PROJECTS orderby proj.NAME select proj);
                usableSuperProjectSource.DataSource = (from sPrj in man.SUPERPROJECTS
                                                       orderby sPrj.NAME
                                                       select sPrj);
            }

            usableProjectlbx.DisplayMember = "Name";
            usableProjectlbx.ValueMember = "URL";
            usableProjectlbx.DataSource = usableProjectSource;

            usableSuperProjectlbx.DisplayMember = "Name";
            usableSuperProjectlbx.ValueMember = "DefaultDirectory";
            usableSuperProjectlbx.DataSource = usableSuperProjectSource;


            var countAdminPrj = (from perm in man.ActiveUser.PERMISSIONS
                                 where perm.PADMIN > 0
                                 select perm).Count();

            if (man.ActiveUser.ISADMIN == 1 || countAdminPrj > 0)
                adminSPrhGrp.Enabled = true;
            else
            {
                newPrjGrp.Location = adminSPrhGrp.Location;
                adminSPrhGrp.Enabled = false;
                adminSPrhGrp.Visible = false;
                groupBox1.Enabled = false;
                groupBox1.Visible = false;
                closeBtn.Location = new Point(newPrjGrp.Location.X + ((newPrjGrp.Size.Width - closeBtn.Width) / 2)+10, newPrjGrp.Location.Y + newPrjGrp.Size.Height + 10);
                this.Size = new Size(newPrjGrp.Right + 10, closeBtn.Bottom + 35);
            }

            inizialize = false;
        }

        private void currentSuperPrjcmb_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(!inizialize)
                updateCurrentConfiguration();

            modifyDependBtn.Enabled = true;
            removeDependBtn.Enabled = true;
        }

        private void delBtn_Click(object sender, EventArgs e)
        {
            SUPERPROJECT currentSuperPrj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;

            var man = (Owner as StartForm).DataManager;

            var lblsuperPrj = (from lblSuperPrj in currentSuperPrj.LABEL_SUPERPROJECTS
                          where lblSuperPrj.ID_LABEL == 1
                          select lblSuperPrj).SingleOrDefault();

            foreach (PROJECT prj in currentCfglbx.SelectedItems)
            {
                var foundelement = (from lblPrj in lblsuperPrj.LABEL_PROJECTS.CreateSourceQuery().Include("LABEL").Include("PROJECT")
                                    where lblPrj.ID_PROJECT == prj.ID
                                    select lblPrj).FirstOrDefault();

                if (foundelement != null)
                {
                    lblsuperPrj.LABEL_PROJECTS.Load();
                    lblsuperPrj.LABEL_PROJECTS.Remove(foundelement);
                }
            }

            man.SaveChanges();

            updateCurrentConfiguration();
        }

        private void usableSuperProjectlbx_SelectedIndexChanged(object sender, EventArgs e)
        {
            addDependBtn.Enabled = true;
        }

        private void currentDependsCfglbx_SelectedIndexChanged(object sender, EventArgs e)
        {            
            delDependBtn.Enabled = true;
            if (usableProjectlbx.SelectedItems.Count == 1)
            {
                modifyBtn.Enabled = true;
                removeBtn.Enabled = true;
            }
            else {
                modifyBtn.Enabled = false;
                removeBtn.Enabled = false;
            }
        }

        private void addDependBtn_Click(object sender, EventArgs e)
        {
            SUPERPROJECT currentSuperPrj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;
            var man = (Owner as StartForm).DataManager;
            var lblSPrj = (from lbl in currentSuperPrj.LABEL_SUPERPROJECTS.CreateSourceQuery().Include("LABEL_SUPERPROJECTS_CHILD")
                           where lbl.ID_LABEL == 1
                           select lbl).FirstOrDefault();
            foreach (SUPERPROJECT sprj in usableSuperProjectlbx.SelectedItems)
            {
                var lblsprj = (from lblsp in man.LABEL_SUPERPROJECTS
                               where lblsp.ID_LABEL == 1 && lblsp.ID_SUPERPROJECT == sprj.ID
                               select lblsp).FirstOrDefault();
                lblSPrj.LABEL_SUPERPROJECTS_CHILD.Add(lblsprj);
            }

            man.SaveChanges();

            updateCurrentConfiguration();
        }

        private void delDependBtn_Click(object sender, EventArgs e)
        {
            SUPERPROJECT currentSuperPrj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;
            var man = (Owner as StartForm).DataManager;
            var lblSPrj = (from lbl in currentSuperPrj.LABEL_SUPERPROJECTS.CreateSourceQuery().Include("LABEL_SUPERPROJECTS_CHILD")
                           where lbl.ID_LABEL == 1
                           select lbl).FirstOrDefault();

            foreach (SUPERPROJECT sprj in currentDependsCfglbx.SelectedItems)
            {
                var lblsprj = (from lblsp in man.LABEL_SUPERPROJECTS
                               where lblsp.ID_LABEL == 1 && lblsp.ID_SUPERPROJECT == sprj.ID
                               select lblsp).FirstOrDefault();

                lblSPrj.LABEL_SUPERPROJECTS_CHILD.Remove(lblsprj);
            }

            man.SaveChanges();


            updateCurrentConfiguration();
        }

        private void importBtn_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                var man = (Owner as StartForm).DataManager;

                var projectTable = man.PROJECTS;
                var files = System.IO.Directory.GetFiles(folderBrowserDialog.SelectedPath, "entries", System.IO.SearchOption.AllDirectories);
                foreach (var file in files)
                {
                    string fullText = System.IO.File.ReadAllText(file);
                    int index = fullText.IndexOf("/trunk\n");
                    if (index != -1)
                    {
                        int firstIndex = fullText.LastIndexOf("http", index);
                        string urlSVN = fullText.Substring(firstIndex, index - firstIndex);
                        int slashIndex = urlSVN.LastIndexOf('/');
                        string projectName = urlSVN.Substring(slashIndex+1);
                        projectName = projectName.Replace("%20", " ");                        

                        PROJECT prj = null;
                        if (projectTable.Count() > 0)
                            foreach (var pippo in projectTable)
                            {
                                if (pippo.NAME == projectName)
                                    prj = pippo;
                            }

                        if (prj == null)
                        {
                            PROJECT proj = new PROJECT();
                            proj.NAME = projectName;
                            proj.URL = urlSVN;
                            proj.LABEL_PROJECTS.Add(new LABEL_PROJECTS() {
                                LABEL = labelTrunk,
                                PROJECT = proj,
                            });
                            man.AddToPROJECTS(proj);

                            try
                            {
                                man.SaveChanges();
                            }
                            catch (Exception ex)
                            { }
                        }
                    }
                }
                updateCurrentConfiguration();
            }
        }

        private void modifyDependBtn_Click(object sender, EventArgs e)
        {
            SUPERPROJECT sprj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;
            superProjectNameTxt.Text = sprj.NAME;
            superProjectNameTxt.ReadOnly = true;
            defaultDirTxt.Text = sprj.DEFAULTDIRECTORY;
        }

        private void removeDependBtn_Click(object sender, EventArgs e)
        {
            SUPERPROJECT sprj = usableSuperProjectlbx.SelectedItems[0] as SUPERPROJECT;
        }

        private void modifyBtn_Click(object sender, EventArgs e)
        {
            PROJECT prj = usableProjectlbx.SelectedItems[0] as PROJECT;
            projectNameTxt.Text = prj.NAME;
            projectNameTxt.ReadOnly = true;
            urlTxt.Text = prj.URL;
        }

        private void removeBtn_Click(object sender, EventArgs e)
        {
            PROJECT prj = usableProjectlbx.SelectedItems[0] as PROJECT;
        }

        private void deleteSPrjBtn_Click(object sender, EventArgs e)
        {
            var sprj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;
            var man = (Owner as StartForm).DataManager;
            man.DeleteObject(sprj);
        }

        private void modifySPrjBtn_Click(object sender, EventArgs e)
        {
            SUPERPROJECT sprj = currentSuperPrjcmb.SelectedItem as SUPERPROJECT;
            if (sprj != null)
            {
                superProjectNameTxt.Text = sprj.NAME;
                superProjectNameTxt.ReadOnly = true;
                defaultDirTxt.Text = sprj.DEFAULTDIRECTORY;
            }
        }

        private void closeBtn_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                this.Cursor = Cursors.WaitCursor;
                var repoBrowser = new SvnRepoBrowser(GestoreSuperProgetto.Properties.Settings.Default.SVNStartUrl, (Owner as StartForm)._client);
                this.Cursor = Cursors.Arrow;
                if (repoBrowser.ShowDialog() == DialogResult.OK)
                {
                    var targetPath = folderBrowserDialog.SelectedPath;
                    

                    var projectName = repoBrowser.UrlSelected.Substring(
                        repoBrowser.UrlSelected.LastIndexOf('/')+1);
                    var projectUrl = repoBrowser.UrlSelected + "/";

                    do{
                        var returnVal = MessageBox.Show(string.Format("L'url di destinazione sarà \n\n\t{0}\n\nSei sicuro di voler continuare?", projectUrl + "trunk"), "Backup Progetto", MessageBoxButtons.YesNoCancel);
                        if (returnVal == DialogResult.No)
                        {
                            if (repoBrowser.ShowDialog() == DialogResult.OK)
                            { }

                            projectName = repoBrowser.UrlSelected.Substring(
                            repoBrowser.UrlSelected.LastIndexOf('/') + 1);
                            projectUrl = repoBrowser.UrlSelected + "/";
                        }
                        else if (returnVal == System.Windows.Forms.DialogResult.Cancel)
                            return;
                        else if (returnVal == System.Windows.Forms.DialogResult.Yes)
                            break;
                    }while(true);

                    if (MessageBox.Show("Vuoi effettaure una copia di backup prima di rilasciare il progetto?", "Backup Progetto", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        (Owner as StartForm).CopyAll(new DirectoryInfo(targetPath),
                            new DirectoryInfo(Path.Combine(Directory.GetParent(targetPath).FullName,
                                                           new DirectoryInfo(targetPath).Name + "_Backup")));
                    }

                    try
                    {
                        var uris = new Uri[] { 
                            new Uri(projectUrl + "trunk"),
                            new Uri(projectUrl + "branches"),
                            new Uri(projectUrl + "tags")};
                        var createArg = new SvnCreateDirectoryArgs()
                        {
                            LogMessage = "Preperazione per Rilascio Progetto: " + projectName
                        };
                        (Owner as StartForm)._client.RemoteCreateDirectories(uris, createArg);

                        var arg = new SvnImportArgs() { LogMessage = "Rilascio Progetto: " + projectName };

                        (Owner as StartForm)._client.Import(targetPath, uris[0], arg);


                        var man = (Owner as StartForm).DataManager;

                        PROJECT proj = new PROJECT()
                        {
                            NAME = projectName,
                            URL = projectUrl,
                        };
                        man.AddToPROJECTS(proj);

                        man.AddToLABEL_PROJECTS(new LABEL_PROJECTS()
                        {
                            LABEL = labelTrunk,
                            PROJECT = proj,
                        });

                        man.SaveChanges();

                        updateCurrentConfiguration();

                        MessageBox.Show("Importazione Progetto: \n\n\t" + projectName + " avvenuta con successo", "Importazione Progetto", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Eccezione durante la pubblicazione della cartella.\nMessaggio: " + ex.Message);
                    }
                }
            }
        }

        private void browseRepoBtn_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            var repoBrowser = new SvnRepoBrowser(GestoreSuperProgetto.Properties.Settings.Default.SVNStartUrl, (Owner as StartForm)._client);
            this.Cursor = Cursors.Arrow;
            if (repoBrowser.ShowDialog() == DialogResult.OK)
            {
                var url = repoBrowser.UrlSelected.Substring(0,
                        repoBrowser.UrlSelected.LastIndexOf('/'));

                urlTxt.Text = url + "/";
                var projectName = url.Substring(url.LastIndexOf('/') + 1);

                projectNameTxt.Text = projectName;
            }
        }
    }
}
